﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using HA.ModFlow.Domain.DomainLayer;

using DotSpatial.Topology;





namespace HA.Data
{
    [Serializable]
   public class ConceptualModel:CoverageBase
   {

       #region 构造函数

       public ConceptualModel()
        {
            this._model = new GWModflow();
            this._model.ModelName = this.Name;


           
 
        }


       public ConceptualModel(GWModflow model)
        {

            this._model = model;

            this._model.ModelName = this.Name;


        }


       #endregion


        #region 事件模型
        [field: NonSerialized]

        public event EventHandler<CollecionChangedEventArgs> CollectionChanged;




        [field: NonSerialized]
        public event EventHandler NameChanged;

        #endregion

        MapDataCollecion _parentMapData;

        public MapDataCollecion ParentMapData
        {
            get { return _parentMapData; }
            set { _parentMapData = value; }
        }


        GWModelType _currentModelType=GWModelType.MODFLOW;

        public GWModelType CurrentModelType
        {
            get { return _currentModelType; }
            set { _currentModelType = value; }
        }



        GWModflow _model;

        public GWModflow Model
        {
            get { return _model; }
            set {


                if (this._model.ModelName!=value.ModelName)
                {
                    this._model.ModelName = value.ModelName;
                    this.Name = this._model.ModelName;

                    
                }

                if (this._model.InnerPack!=value.InnerPack)
                {

                    this._model.InnerPack = value.InnerPack;
                }


                if (this._model.IsTransPort != value.IsTransPort)
                {
                    this._model.IsTransPort = value.IsTransPort;

                }



                ///不知道这个不等号有多少效果

                if (this.IsSpeChanged(this._model.SpeList,value.SpeList))
                {
                    this._model.SpeList.Clear();

                    this._model.SpeList.AddRange(value.SpeList);

                    this.OnSpeListChanged();

                    
                }


               //判断应力期个数是否有变化

                if (this._model.NPeriods!=value.NPeriods)
                {
                    this._model.NPeriods = value.NPeriods;

                    //this.OnNPeriodsChanged();
                }

                }


        }


        protected bool IsSpeChanged(List<MT3DMS.DomainLayer.MTSpecies> org, List<MT3DMS.DomainLayer.MTSpecies> now)
        {

            if (now.Count!=org.Count)
            {
                return true;
                
            }

            for (int i = 0; i < org.Count; i++)
            {
                if (org[i].Name != now[i].Name || org[i].SpeiesMoblie != now[i].SpeiesMoblie)
                {
                    return true;
                }
            }


            return false;


        }


        protected void OnSpeListChanged()
        {

            foreach (Coverage item in this.Coverages)
            {

                item.OnSpeListChanged();


            }
 
        }



        //protected void OnNPeriodsChanged()
        //{

        //    foreach (Coverage item in this.Coverages)
        //    {

        //        item.OnNPeriodsChanged();


        //    }
 
        //}





        protected override void OnsetName()
        {
            base.OnsetName();
            this._model.ModelName = this.Name;

            if (NameChanged != null)
            {
                NameChanged(this, new EventArgs());

            }


        }




        List<Coverage> _coverages=new List<Coverage> ();

        public List<Coverage> Coverages
        {
            get { return _coverages; }
         
        }

        //由一下具体图层代替
        int _coverageBase = 1;

        int _objectLayerBase = 1;
        int _bounderLayerBase = 1;
        int _extLayerBase = 1;
        int _rechrgLayerBase = 1;
        int _geoLayerBase = 1;

        #region 内部函数

        protected void BuildLayerIJK(List<Coverage> coverages,GridData grid)
        {


            List<int[,]> ibound = grid.WaterGrid.GetIBounds();

            this.BuildLayerIJK(coverages,grid,ibound);



            //需要在最外围构建一次网格的碰撞模型

            //int nrows = grid.RowsCount;
            //int ncols = grid.ColsCount;



            //Polygon[,] poly = new Polygon[nrows, ncols];


            //HAMath.Point2D[,] ptBoundary = grid.GetBoundaryGrid2D();


            //for (int i = 0; i < nrows; i++)
            //{
            //    for (int j = 0; j < ncols; j++)
            //    {

            //        List<Coordinate> coords = new List<Coordinate>();

            //        Coordinate c1 = new Coordinate(ptBoundary[i, j].X, ptBoundary[i, j].Y);
            //        Coordinate c2 = new Coordinate(ptBoundary[i, j + 1].X, ptBoundary[i, j + 1].Y);
            //        Coordinate c3 = new Coordinate(ptBoundary[i + 1, j + 1].X, ptBoundary[i + 1, j + 1].Y);
            //        Coordinate c4 = new Coordinate(ptBoundary[i + 1, j].X, ptBoundary[i + 1, j].Y);

            //        coords.Add(c1);
            //        coords.Add(c2);
            //        coords.Add(c3);
            //        coords.Add(c4);

            //        LinearRing lr = new LinearRing(coords);




            //        Polygon p = new Polygon(lr);


            //        poly[i, j] = p;


            //    }

            //}



            ////准备开始各自的碰撞监测，需要考虑有效性

            //List<int[,]> ibound = grid.WaterGrid.GetIBounds();

            //foreach (Coverage item in coverages)
            //{

            //    item.BuildFeatureObjectIJK(poly, ibound);



            //}




             

 
        }


        /// <summary>
        /// 构建对应的ijk列表，但不考虑IBOUND的影响
        /// </summary>
        /// <param name="coverages"></param>
        /// <param name="grid"></param>
        protected void BuildLayerIJK(List<Coverage> coverages, GridData grid, List<int[,]> ibound)
        {

            //需要在最外围构建一次网格的碰撞模型

            int nrows = grid.RowsCount;
            int ncols = grid.ColsCount;


            Polygon[,] poly = new Polygon[nrows, ncols];


            HAMath.Point2D[,] ptBoundary = grid.GetBoundaryGrid2D();

            Polygon framePoly = new Polygon
                (new LinearRing(
                    new List<Coordinate>(4) 
                    {
                        new Coordinate(ptBoundary[0, 0].X, ptBoundary[0, 0].Y),
                        new Coordinate(ptBoundary[0, ncols].X, ptBoundary[0, ncols].Y),
                        new Coordinate(ptBoundary[nrows, ncols].X, ptBoundary[nrows, ncols].Y),
                        new Coordinate(ptBoundary[nrows,0].X, ptBoundary[nrows, 0].Y)
                    }//List
                  )//linearing
                );//polygon

            for (int i = 0; i < nrows; i++)
            {
                for (int j = 0; j < ncols; j++)
                {

                    List<Coordinate> coords = new List<Coordinate>();

                    Coordinate c1 = new Coordinate(ptBoundary[i, j].X, ptBoundary[i, j].Y);
                    Coordinate c2 = new Coordinate(ptBoundary[i, j + 1].X, ptBoundary[i, j + 1].Y);
                    Coordinate c3 = new Coordinate(ptBoundary[i + 1, j + 1].X, ptBoundary[i + 1, j + 1].Y);
                    Coordinate c4 = new Coordinate(ptBoundary[i + 1, j].X, ptBoundary[i + 1, j].Y);

                    coords.Add(c1);
                    coords.Add(c2);
                    coords.Add(c3);
                    coords.Add(c4);

                    LinearRing lr = new LinearRing(coords);




                    Polygon p = new Polygon(lr);


                    poly[i, j] = p;


                }

            }




            //开始执行具体的构造过程


            foreach (Coverage item in coverages)
            {

                item.BuildFeatureObjectIJK(poly, ibound, framePoly);



            }






        }

        #endregion

        #region 公共函数


        public Coverage NewCoverage(HAUtil.LAYERCOVERAGETYPE type)
        {
            Coverage cov = new Coverage(type,(CoverageSetup)this._model.CoverageSetup.Clone());

            switch (type)
            {
                case HAUtil.LAYERCOVERAGETYPE.对象层:
                    cov.Name = "对象" + this._objectLayerBase++;
                    break;
                case HAUtil.LAYERCOVERAGETYPE.边界层:
                    cov.Name = "边界" + this._bounderLayerBase++;
                    break;
                case HAUtil.LAYERCOVERAGETYPE.蒸散层:
                    cov.Name = "蒸散" + this._extLayerBase++;
                    break;
                case HAUtil.LAYERCOVERAGETYPE.补给层:
                    cov.Name = "补给" + this._rechrgLayerBase++;
                    break;
                case HAUtil.LAYERCOVERAGETYPE.水文地质层:
                    cov.Name = "水文地质" + this._geoLayerBase++;
                    break;
                default:
                    break;
            }


            return cov;
 
        }


        /// <summary>
        /// 激活modlfow中的有效单元，
        /// </summary>
        /// <param name="modflow"></param>
        public void ActivateCellsInModflow(ModFlowData modflow)
        {


            #region 相关数据的初始化和有效性检验

            //List<int[,]> effectiveCell=new List<int[,]> ()  ;


            GridData gridData = modflow.GridData;
            if (gridData == null)
            {
                return;
            }
            if (gridData.LayersCount<=0 )
            {
                return;   
            }
            //BoundGrid boundGrid = gridData.GetBoundGrid();

            //if (boundGrid == null)
            //{
            //    return ;
            //}

          
           //用于存储结果的数组

            int nrows = gridData.RowsCount;

            int ncols = gridData.ColsCount;

            int nlayers = gridData.LayersCount;

            //初始化为无效值 0

            //int[, ,] result = new int[nrows, ncols,nlayers];

            List<int[,]> result2 = new List<int[,]>();

            for (int k = 0; k < nlayers; k++)
            {
                int[,] layer=new int[nrows,ncols];

                result2.Add(layer);
                
            }



            //最原始的有效多边形

            //List<PolygonFO> polys = new List<PolygonFO>();

            List<List<Polygon>> layerPolygon = new List<List<Polygon>>();


            //初始化对应的多边形

            for (int i = 0; i < nlayers; i++)
            {
                List<Polygon> lst = new List<Polygon>();

                layerPolygon.Add(lst);
                
            }


            ///循环图层，取得所有的可用polygon
            ///
            foreach (Coverage item in this._coverages)
            {
                if (item.Setup.IsUseForModelBoundary)
                {

                    foreach (FeatureObject fo in item.Featureobjects)
                    {
                        if (fo is PolygonFO)
                        {
                            PolygonFO py = fo as PolygonFO;


                        

                          

                            List<Coordinate> coord = new List<Coordinate>();
                            foreach (HAUtil.HCoordinate hc in py.Coords)
                            {
                                Coordinate c = new Coordinate(hc.X, hc.Y);
                                coord.Add(c);
                            }

                            List<List<Coordinate>> holes = new List<List<Coordinate>>();

                            List<Coordinate> hole;

                            if (py.InnerHoles != null && py.InnerHoles.Count > 0)
                            {
                                foreach (List<HAUtil.HCoordinate> holehc in py.InnerHoles)
                                {
                                    hole = new List<Coordinate>();
                                    foreach (HAUtil.HCoordinate hCoordinate in holehc)
                                    {
                                        Coordinate c = new Coordinate(hCoordinate.X, hCoordinate.Y);
                                        hole.Add(c);
                                    }
                                    holes.Add(hole);
                                }
                            }





                            List<LinearRing> lstHoles = new List<LinearRing>();

                            foreach (List<Coordinate> l in holes)
                            {
                                LinearRing lr = new LinearRing(l);

                                lstHoles.Add(lr);

                                
                            }
                            
                            
                            LinearRing lrOut = new LinearRing(coord);


                            ///本层所指示的多边形
                            Polygon p;

                            if (holes.Count > 0)
                            {

                                p = new Polygon(lrOut, lstHoles.ToArray ());


                            }
                            else
                            {
                                p = new Polygon(lrOut);
                            }




                            int layerStart=item.Setup.LayerStart;
                            int layerEnd = item.Setup.LayerEnd;

                            ///开始考虑对应的有效性选项,首先是图层特性
                            ///

                            if (item.Setup.ScTypes[MAPSCType.LAYERRANGE] == true)
                            {



                                layerStart = py.LayerRange.FromLayer;

                                layerEnd = py.LayerRange.ToLayer;

                               


                            }



                            //开始为每一层 添加对应的项目


                            for (int i = layerStart-1; i < layerEnd; i++)
                            {

                                ///当i在有效范围的时候

                                if (i<nlayers&&i>-1)
                                {

                                    layerPolygon[i].Add(p);

                                    
                                }
                                
                            }


                          

                        }
                        
                    }



                }
            }







            //开始循环所有中心点坐标，以确定对应的包含关系

            //这里每一层的中心点都是一致的 ,所以这里只取了第一层

            HAMath.Point2D[,] ptArray = gridData.GetElevationCoords2D();


            for (int k = 0; k < nlayers; k++)
            {
                for (int i = 0; i < nrows; i++)
                {

                    for (int j = 0; j < ncols; j++)
                    {

                        Point p=new Point (ptArray[i,j].X,ptArray[i,j].Y);

                        //开始逐层寻找

                        foreach (Polygon poly in layerPolygon[k])
                        {
                            if (poly.Contains(p))
                            {

                                //result[i, j, k] = 1;

                                result2[k][i, j] = 1;


                                /// 继续下一个循环，关于这一语句，怎样跳出 一层循环

                                break;
                                
                                
                            }
                            
                        }



                        
                    }
                    
                }
                
            }




            //这里开始考虑多边形边框线多带来的影响


            //因为没有提供单独的构建函数，所以这里全部从新构建了一遍IJK列表

            List<int[,]> ibound = new List<int[,]>();

            for (int k = 0; k < nlayers; k++)
            {

                int[,] b = new int[nrows, ncols];

                for (int i = 0; i < nrows; i++)
                {
                    for (int j = 0; j < ncols; j++)
                    {
                        b[i, j] = 1;

                        
                    }
                    
                }


                ibound.Add(b);

                
            }


            this.BuildLayerIJK(this.Coverages,gridData,ibound);


           


            foreach (Coverage item in this._coverages)
            {
                if (item.Setup.IsUseForModelBoundary)
                {

                    foreach (FeatureObject fo in item.Featureobjects)
                    {
                        if (fo is PolygonFO)
                        {
                            PolygonFO py = fo as PolygonFO;


                            //循环外边界

                            foreach (LineAndDirection ld in py.RelationLines)
                            {
                                if (ld.Line.GetCurrentBCType() != null)
                                {

                                    foreach (ValueResult vr in ld.Line.LstIJK)
	                                {

                                         result2[vr.K-1][vr.I-1, vr.J-1] = 1;

		 
	                                }
 
                                }
                                
                            }


                            //循环所有的内边界,多个洞的情况


                            foreach (List<LineAndDirection> lstInnerLines in py.HoleRelationLines)
	                        {


                                  foreach (LineAndDirection ld in lstInnerLines)
                                {
                                    if (ld.Line.GetCurrentBCType() != null)
                                    {

                                        foreach (ValueResult vr in ld.Line.LstIJK)
	                                    {

                                             result2[vr.K-1][vr.I-1, vr.J-1] = 1;

		 
	                                    }
 
                                    }
                                
                                }

		 
	                        }
                           

                        }
                    }
                }
            }




            //将结果返还


            modflow.GridData.WaterGrid.SetIBounds(result2);



            #endregion 


         


 
        }


        /// <summary>
        /// 对外映射主函数，包含所有图册
        /// </summary>
        /// <param name="modflow"></param>
        public void MapToModflow(ModFlowData modflow,bool isNewModflow)
        {
            this.MapToModflow(modflow, this._coverages,isNewModflow);
         
 
        }


        /// <summary>
        /// 可以对指定的图层子集惊醒映射
        /// </summary>
        /// <param name="modflow"></param>
        /// <param name="coverages"></param>
        public void MapToModflow(ModFlowData modflow, List<Coverage> coverages,bool isNewModflow,bool isSingleLayer = false)
        {
            //判断是否手动设置应力期
            List<double> _strPeriods = new List<double>() { 0 };

            if (isSingleLayer)
            {
                foreach (var item in modflow.StressPeriods.InnerList)
                {
                    _strPeriods.Add(item.PERLEN + _strPeriods[_strPeriods.Count - 1]);
                }
                _strPeriods.RemoveAt(0);
            }
            else if (this.ParentMapData.IsManualSetStressPeriod)
            {
                if (this.ParentMapData.StressPeriods.InnerList.Count <= 0)
                    return;
                foreach (var item in this.ParentMapData.StressPeriods.InnerList)
                {
                    _strPeriods.Add(item.PERLEN + _strPeriods[_strPeriods.Count - 1]);
                }
                _strPeriods.RemoveAt(0);
            }
            else
            {
                foreach (Coverage c in coverages)
                {
                    foreach (var item in c.Featureobjects)
                    {
                        switch (item.SelectedSCType)
                        {
                            case MAPSCType.WELL:

                                foreach (var bcData in (item as PointFO).Well.MultiFlowRate.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }

                                break;
                            case MAPSCType.SPECIFIEDHEAD:
                                foreach (var bcData in item.SpecifiedHead.MultiStage.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.SpecifiedHead.MultiStageEnd.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.SpecifiedHead.MultiStageStart.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                break;
                            case MAPSCType.SPECIFIEDFLOW:
                                if (item is PolygonFO)
                                {
                                    foreach (var bcData in (item as PolygonFO).SpecifiedFlow.MultiSpecifiedFlow.BCDatas)
                                    {
                                        if (!_strPeriods.Contains(bcData.EndTime))
                                            _strPeriods.Add(bcData.EndTime);
                                    }
                                }
                                if (item is LineFO)
                                {
                                    foreach (var bcData in (item as LineFO).SpecifiedFlow.MultiSpecifiedFlow.BCDatas)
                                    {
                                        if (!_strPeriods.Contains(bcData.EndTime))
                                            _strPeriods.Add(bcData.EndTime);
                                    }
                                }
                                break;
                            case MAPSCType.GENERALHEAD:

                                foreach (var bcData in item.GeneralHead.MultiConductance.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }

                                foreach (var bcData in item.GeneralHead.MultiEndHead.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }

                                foreach (var bcData in item.GeneralHead.MultiHeadStage.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }

                                foreach (var bcData in item.GeneralHead.MultiStartHead.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                break;
                            case MAPSCType.DRAIN:

                                foreach (var bcData in item.Drain.MultiConductance.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.Drain.MultiElevation.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.Drain.MultiEndElevation.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.Drain.MultiStartElevation.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                break;
                            case MAPSCType.RIVER:
                                foreach (var bcData in item.River.MultiConductance.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.River.MultiElevation.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.River.MultiendElevation.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.River.MultiEndStage.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.River.MultiStage.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.River.MultiStartStage.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.River.MultiStratElevation.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }

                                break;
                            case MAPSCType.SEEPAGEFACE:
                                foreach (var bcData in item.Seepage.MultiConductance.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.Seepage.MultiElevOffSet.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.Seepage.MultiElevOffSetEnd.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.Seepage.MultiElevOffSetStart.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                break;
                            case MAPSCType.SPECIFIEDCONC:
                                foreach (var spec in item.SpecConc.SpecConc)
                                {
                                    foreach (var bcData in spec.DateDatas.BCDatas)
                                    {
                                        if (!_strPeriods.Contains(bcData.EndTime))
                                            _strPeriods.Add(bcData.EndTime);
                                    }
                                }
                                break;
                            case MAPSCType.MASSLOADING:
                                foreach (var spec in item.MassLoading.SpecConc)
                                {
                                    foreach (var bcData in spec.DateDatas.BCDatas)
                                    {
                                        if (!_strPeriods.Contains(bcData.EndTime))
                                            _strPeriods.Add(bcData.EndTime);
                                    }
                                }
                                break;
                            default:
                                break;
                        }

                        if ((item as PolygonFO) != null)
                        {
                            foreach (var bcData in (item as PolygonFO).ArealPropertyData.EtExtDepthV2.DateDatas.BCDatas)
                            {
                                if (!_strPeriods.Contains(bcData.EndTime))
                                    _strPeriods.Add(bcData.EndTime);
                            }
                            foreach (var bcData in (item as PolygonFO).ArealPropertyData.EtRateV2.DateDatas.BCDatas)
                            {
                                if (!_strPeriods.Contains(bcData.EndTime))
                                    _strPeriods.Add(bcData.EndTime);
                            }
                            foreach (var bcData in (item as PolygonFO).ArealPropertyData.MaxETRateV2.DateDatas.BCDatas)
                            {
                                if (!_strPeriods.Contains(bcData.EndTime))
                                    _strPeriods.Add(bcData.EndTime);
                            }
                            foreach (var spec in (item as PolygonFO).ArealPropertyData.RechargeConc.SpecConc)
                            {
                                foreach (var bcData in spec.DateDatas.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                            }
                            foreach (var bcData in (item as PolygonFO).ArealPropertyData.RechargeRate.DateDatas.BCDatas)
                            {
                                if (!_strPeriods.Contains(bcData.EndTime))
                                    _strPeriods.Add(bcData.EndTime);
                            }

                        }
                    }

                }
                //排序
                _strPeriods.Sort();
                _strPeriods.RemoveAt(0);

                


                //this.ParentMapData.StressPeriods.InnerList.Clear();
                //foreach (var item in _strPeriods)
                //{
                //    this.ParentMapData.StressPeriods.InnerList.Add(new StressPeriod() { PERLEN = item-前一个 });
                //}
            }

            if (_strPeriods.Count == 0)
                return;

            if (!isNewModflow && modflow.StressPeriods.InnerList.Count != _strPeriods.Count)
            {
                if (System.Windows.MessageBox.Show("概念映射部分的应力期设置与modflow的应力期设置不同，是否覆盖？", "提示", System.Windows.MessageBoxButton.YesNo, System.Windows.MessageBoxImage.Information) == System.Windows.MessageBoxResult.No)
                    return;
            }

            modflow.StressPeriods.InnerList.Clear();
            for (int i = 0; i < _strPeriods.Count; i++)
            {
                modflow.StressPeriods.InnerList.Add(new StressPeriod() { PERLEN = i == 0 ? _strPeriods[i] : (_strPeriods[i] - _strPeriods[i - 1]) });
            }
            modflow.StressPeriods.ResetStressPeriods(modflow.StressPeriods.InnerList,true);

            modflow.ModelOption.InnerPack = this.Model.InnerPack;

            //更新一些主属性选项
            GWModflow mod = this._model as GWModflow;

            if (mod != null)
            {


                //判断当前应力期数是否与此处设置相同
                //if (modflow.StressPeriods.InnerList.Count != mod.NPeriods)
                if (modflow.StressPeriods.InnerList.Count != _strPeriods.Count)
                {
                   System.Windows. MessageBox.Show("概念映射部分的应力期设置与modflow的应力期设置不同，请修正！");

                    return;
                    
                }



                if (modflow.ModelOption.InnerPack != mod.InnerPack)
                {
                    modflow.ModelOption.InnerPack = mod.InnerPack;

                }


                



                //重建对应的IJKs

                this.BuildLayerIJK(coverages,modflow.GridData);




                foreach (Coverage item in coverages)
                {
                    item.MapToModflow(_strPeriods,modflow);

                }


                //这里对于源汇进行特殊的处理,

                //首先找到所有的选择项中的源汇类型

                List<MAPSCType> types = new List<MAPSCType>();

                foreach (Coverage item in coverages)
                {
                    foreach (KeyValuePair<MAPSCType, bool> kv in item.Setup.ScTypes)
                    {

                        if (kv.Value == true)
                        {

                            if (!types.Contains(kv.Key))
                            {
                                types.Add(kv.Key);

                            }



                        }


                    }

                }


                if (types.Contains(MAPSCType.RIVER))
                {
                    modflow.SourceSinks.Rivers.Enabled = true;
                    modflow.SourceSinks.Rivers.CommitTempRivers();
                }

                if (types.Contains(MAPSCType.SPECIFIEDHEAD))
                {
                    modflow.SourceSinks.SpecifiedHeads.Enabled = true;
                    modflow.SourceSinks.SpecifiedHeads.CommitTempSpecifiedHeads();
                }

                if (types.Contains(MAPSCType.GENERALHEAD))
                {
                    modflow.SourceSinks.GeneralHeads.Enabled = true;
                    modflow.SourceSinks.GeneralHeads.CommitTempGeneralHeads();
                }

                if (types.Contains(MAPSCType.DRAIN) || types.Contains(MAPSCType.SEEPAGEFACE))
                {
                    modflow.SourceSinks.Drains.Enabled = true;
                    modflow.SourceSinks.Drains.CommitTempDrains();

                }




                if (types.Contains(MAPSCType.WELL) || types.Contains(MAPSCType.SPECIFIEDFLOW))
                {
                    modflow.SourceSinks.Wells.Enabled = true;
                    modflow.SourceSinks.Wells.CommitTempWells();
                }

                if (types.Contains(MAPSCType.BARRIER))
                {
                    modflow.HfbData.Enabled = true;
                    modflow.HfbData.CommitTempHFBItems();
                }


                //关于面妆源汇的高程刷新

                List<MAPArealType> areaTypes = new List<MAPArealType>();


                foreach (Coverage item in coverages)
                {
                    foreach (KeyValuePair<MAPArealType, bool> kv in item.Setup.ArealTypes)
                    {

                        if (kv.Value == true)
                        {

                            if (!areaTypes.Contains(kv.Key))
                            {
                                areaTypes.Add(kv.Key);

                            }



                        }


                    }

                }


                //刷新对应的高程视图，如果有这一选项的话

                if (areaTypes.Contains(MAPArealType.BOTELVE)||areaTypes.Contains(MAPArealType.TOPELVE))
                {

                    modflow.GridData.AskElevationChanged();


                }

             


            }



 
        }


        public void MapToMT3DMS( HA.MT3DMS.DomainLayer.MT3DMSData data,bool isNewMT3D)
        {
            this.MapToMT3DMS(data,this._coverages,isNewMT3D);
        }




        public void MapToMT3DMS(HA.MT3DMS.DomainLayer.MT3DMSData data, List<Coverage> coverages,bool isNewMt3D,bool isSingleLayer = false)
        {
            //判断是否手动设置应力期
            List<double> _strPeriods = new List<double>() { 0 };
            if (isSingleLayer)
            {
                foreach (var item in data.BasicTransport.StressPeriod.Periods)
                {
                    _strPeriods.Add(item.PERLEN + _strPeriods[_strPeriods.Count - 1]);
                }
                _strPeriods.RemoveAt(0);
            }
            else if (this.ParentMapData.IsManualSetStressPeriod)
            {
                if (this.ParentMapData.StressPeriods.InnerList.Count <= 0)
                    return;
                foreach (var item in this.ParentMapData.StressPeriods.InnerList)
                {
                    _strPeriods.Add(item.PERLEN + _strPeriods[_strPeriods.Count - 1]);
                }
                _strPeriods.RemoveAt(0);
            }
            else
            {
                foreach (Coverage c in coverages)
                {
                    foreach (var item in c.Featureobjects)
                    {
                        switch (item.SelectedSCType)
                        {
                            case MAPSCType.WELL:

                                foreach (var bcData in (item as PointFO).Well.MultiFlowRate.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }

                                break;
                            case MAPSCType.SPECIFIEDHEAD:
                                foreach (var bcData in item.SpecifiedHead.MultiStage.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.SpecifiedHead.MultiStageEnd.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.SpecifiedHead.MultiStageStart.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                break;
                            case MAPSCType.SPECIFIEDFLOW:
                                if (item is PolygonFO)
                                {
                                    foreach (var bcData in (item as PolygonFO).SpecifiedFlow.MultiSpecifiedFlow.BCDatas)
                                    {
                                        if (!_strPeriods.Contains(bcData.EndTime))
                                            _strPeriods.Add(bcData.EndTime);
                                    }
                                }
                                if (item is LineFO)
                                {
                                    foreach (var bcData in (item as LineFO).SpecifiedFlow.MultiSpecifiedFlow.BCDatas)
                                    {
                                        if (!_strPeriods.Contains(bcData.EndTime))
                                            _strPeriods.Add(bcData.EndTime);
                                    }
                                }
                                break;
                            case MAPSCType.GENERALHEAD:

                                foreach (var bcData in item.GeneralHead.MultiConductance.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }

                                foreach (var bcData in item.GeneralHead.MultiEndHead.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }

                                foreach (var bcData in item.GeneralHead.MultiHeadStage.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }

                                foreach (var bcData in item.GeneralHead.MultiStartHead.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                break;
                            case MAPSCType.DRAIN:

                                foreach (var bcData in item.Drain.MultiConductance.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.Drain.MultiElevation.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.Drain.MultiEndElevation.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.Drain.MultiStartElevation.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                break;
                            case MAPSCType.RIVER:
                                foreach (var bcData in item.River.MultiConductance.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.River.MultiElevation.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.River.MultiendElevation.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.River.MultiEndStage.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.River.MultiStage.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.River.MultiStartStage.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.River.MultiStratElevation.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }

                                break;
                            case MAPSCType.SEEPAGEFACE:
                                foreach (var bcData in item.Seepage.MultiConductance.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.Seepage.MultiElevOffSet.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.Seepage.MultiElevOffSetEnd.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                foreach (var bcData in item.Seepage.MultiElevOffSetStart.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                                break;
                            case MAPSCType.SPECIFIEDCONC:
                                foreach (var spec in item.SpecConc.SpecConc)
                                {
                                    foreach (var bcData in spec.DateDatas.BCDatas)
                                    {
                                        if (!_strPeriods.Contains(bcData.EndTime))
                                            _strPeriods.Add(bcData.EndTime);
                                    }
                                }
                                break;
                            case MAPSCType.MASSLOADING:
                                foreach (var spec in item.MassLoading.SpecConc)
                                {
                                    foreach (var bcData in spec.DateDatas.BCDatas)
                                    {
                                        if (!_strPeriods.Contains(bcData.EndTime))
                                            _strPeriods.Add(bcData.EndTime);
                                    }
                                }
                                break;
                            default:
                                break;
                        }
                        if ((item as PolygonFO) != null)
                        {
                            foreach (var bcData in (item as PolygonFO).ArealPropertyData.EtExtDepthV2.DateDatas.BCDatas)
                            {
                                if (!_strPeriods.Contains(bcData.EndTime))
                                    _strPeriods.Add(bcData.EndTime);
                            }
                            foreach (var bcData in (item as PolygonFO).ArealPropertyData.EtRateV2.DateDatas.BCDatas)
                            {
                                if (!_strPeriods.Contains(bcData.EndTime))
                                    _strPeriods.Add(bcData.EndTime);
                            }
                            foreach (var bcData in (item as PolygonFO).ArealPropertyData.MaxETRateV2.DateDatas.BCDatas)
                            {
                                if (!_strPeriods.Contains(bcData.EndTime))
                                    _strPeriods.Add(bcData.EndTime);
                            }
                            foreach (var spec in (item as PolygonFO).ArealPropertyData.RechargeConc.SpecConc)
                            {
                                foreach (var bcData in spec.DateDatas.BCDatas)
                                {
                                    if (!_strPeriods.Contains(bcData.EndTime))
                                        _strPeriods.Add(bcData.EndTime);
                                }
                            }
                            foreach (var bcData in (item as PolygonFO).ArealPropertyData.RechargeRate.DateDatas.BCDatas)
                            {
                                if (!_strPeriods.Contains(bcData.EndTime))
                                    _strPeriods.Add(bcData.EndTime);
                            }

                        }
                    }

                }
                //排序
                _strPeriods.Sort();
                _strPeriods.RemoveAt(0);
                //this.ParentMapData.StressPeriods.InnerList.Clear();
                //foreach (var item in _strPeriods)
                //{
                //    this.ParentMapData.StressPeriods.InnerList.Add(new StressPeriod() { PERLEN = item-前一个 });
                //}
            }

            if (_strPeriods.Count == 0)
                return;

            if (!isNewMt3D && data.BasicTransport.StressPeriod.Periods.Count != _strPeriods.Count)
            {
                if (System.Windows.MessageBox.Show("概念映射部分的应力期设置与mt3dms的应力期设置不同，是否覆盖？", "提示", System.Windows.MessageBoxButton.YesNo, System.Windows.MessageBoxImage.Information) == System.Windows.MessageBoxResult.No)
                    return;
            }

            //data.MfData.StressPeriods.InnerList.Clear();
            data.BasicTransport.StressPeriod.Periods.Clear();
            for (int i = 0; i < _strPeriods.Count; i++)
            {
                //data.MfData.StressPeriods.InnerList.Add(new StressPeriod() { PERLEN = i == 0 ? _strPeriods[i] : (_strPeriods[i] - _strPeriods[i - 1]) });
                data.BasicTransport.StressPeriod.Periods.Add(new MT3DMS.DomainLayer.MTStressPeriod() { PERLEN = i == 0 ? _strPeriods[i] : (_strPeriods[i] - _strPeriods[i - 1]) });
            }
            //data.MfData.StressPeriods.ResetStressPeriods(data.MfData.StressPeriods.InnerList, true);
            data.BasicTransport.StressPeriod.ResetPeriods(data.BasicTransport.StressPeriod.Periods,true);
            //data.MfData.ModelOption.InnerPack = this.Model.InnerPack;

             //更新一些主属性选项
            GWModflow mod = this._model as GWModflow;

            if (mod != null)
            {

                if (mod.IsTransPort==true)
                {

                    if (mod.TransportModel== MT3DMS.DomainLayer.ModelType.MT3DMS)
                    {

                        //判断当前应力期数是否与此处设置相同
                        //if (data.BasicTransport.StressPeriod.Periods.Count != mod.NPeriods)
                        if (data.BasicTransport.StressPeriod.Periods.Count != _strPeriods.Count)
                        {
                            System.Windows.MessageBox.Show("概念映射部分的应力期设置与mt3dms的应力期设置不同，请修正！");

                            return;

                        }



                        //首先进行污染物的对比,这边类型没有必要做成mtspecies,直接做string 就可以了


                        //首先判断数量，然后判断内容

                        if (mod.SpeList.Count != data.BasicTransport.SpeciesCollecion.SpeciesCount)
                        {
                            System.Windows.MessageBox.Show("概念映射部分的污染物设置与mt3dms的污染物设置不同，请修正！");

                            return;

                        }
                        else
                        {
                            bool bHaveIt = false;

                            foreach (MT3DMS.DomainLayer.MTSpecies sp in mod.SpeList)
                            {

                                foreach (MT3DMS.DomainLayer.MTSpecies item in data.BasicTransport.SpeciesCollecion.Species)
                                {
                                    if (item.Name==sp.Name)
                                    {
                                        bHaveIt = true;
                                        
                                    }
                                    
                                }

                                if (bHaveIt==false)
                                {
                                    System.Windows.MessageBox.Show("概念映射部分的污染物设置与mt3dms的污染物设置不同，请修正！");

                                    return;
                                    
                                }

                            }
 
                        }


                        //开启对应的选项，根据具体的设置

                        //首先是普通类型
                        List<MAPSCType> types = new List<MAPSCType>();

                        foreach (Coverage item in coverages)
                        {
                            foreach (KeyValuePair<MAPSCType, bool> kv in item.Setup.ScTypes)
                            {

                                if (kv.Value == true)
                                {

                                    if (!types.Contains(kv.Key))
                                    {
                                        types.Add(kv.Key);

                                    }



                                }


                            }

                        }


                        if (types.Contains(MAPSCType.MASSLOADING))
                        {
                            data.SourceSinkMixing.Enabled = true;

                            //清空所有massloading类型
                            data.SourceSinkMixing.ClearMixingItems(MT3DMS.DomainLayer.MixingSSType.MASSLOAD);
                            
                        }

                        if (types.Contains(MAPSCType.SPECIFIEDCONC))
                        {
                            data.SourceSinkMixing.Enabled = true;

                            //清空所有massloading类型
                            data.SourceSinkMixing.ClearMixingItems(MT3DMS.DomainLayer.MixingSSType.SECCONC);
                            

                        }


                        //然后是面妆类型


                        List<MAPArealType> areaTypes = new List<MAPArealType>();


                        foreach (Coverage item in coverages)
                        {
                            foreach (KeyValuePair<MAPArealType, bool> kv in item.Setup.ArealTypes)
                            {

                                if (kv.Value == true)
                                {

                                    if (!areaTypes.Contains(kv.Key))
                                    {
                                        areaTypes.Add(kv.Key);

                                    }



                                }


                            }

                        }




                        if (areaTypes.Contains(MAPArealType.LONGDISPERSITY))
                        {

                            data.Dispersion.Enabled = true;


                        }

                        if (areaTypes.Contains(MAPArealType.BULKDENSITY))
                        {

                            data.ChemicalReaction.Enabled = true;


                        }

                        if (areaTypes.Contains(MAPArealType.IMMOBILEPOROSITY))
                        {

                            data.ChemicalReaction.Enabled = true;


                        }
                       


                        //然后构建对应的映射IJK
                        //这里所构建的是基于modflow的有效性，对于mt3dms,需要特殊处理

                        this.BuildLayerIJK(coverages,data.MfData.GridData);



                        //之后准备逐级映射

                        foreach (Coverage c in coverages)
                        {

                            c.MapToMT3DMS(_strPeriods, data);

                        }


                        
                    }



                    
                }



            }
          
        }


        /// <summary>
        /// 取得指定ID的图层
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>

        public Coverage GetCoverage(string id)
        {
            foreach (Coverage  item in this._coverages)
            {
                if (item.Key.ToString()==id)
                {
                    return item;
                    
                }
                
            }

            return null;
        }

        public void AddCoverage(Coverage coverage)
        {

            this._coverages.Add(coverage);
            coverage.ParentCM = this;

            if (this.ParentMapData!=null)
            {

                this.ParentMapData.AskCoverageCollecionChanged(new CoverageCollectionChangedEventArgs(this, coverage, CollectionChangedType.ADD));


                
            }

         
            //coverage.CollecionChanged += new EventHandler<CollecionChangedEventArgs>(coverage_CollecionChanged);

            if (this.CollectionChanged != null)
            {
                this.CollectionChanged(this, new CollecionChangedEventArgs(coverage, CollectionChangedType.ADD));
            }
 
        }

        void coverage_CollecionChanged(object sender, CollecionChangedEventArgs e)
        {
            


        }

        public void RemoveCoverage(Coverage coverage)
        {
          

            this._coverages.Remove(coverage);
            coverage.ParentCM = null;
          

            //coverage.CollecionChanged -= new EventHandler<CollecionChangedEventArgs>(coverage_CollecionChanged);

            if (this.ParentMapData!=null)
            {

                this.ParentMapData.AskCoverageCollecionChanged(new CoverageCollectionChangedEventArgs(this, coverage, CollectionChangedType.REMOVE));

                
            }

          

         

            if (this.CollectionChanged != null)
            {
                this.CollectionChanged(this, new CollecionChangedEventArgs(coverage, CollectionChangedType.REMOVE));
            }

        }


        /// <summary>
        /// 复制并添加指定的图层定义
        /// </summary>
        /// <param name="coverage"></param>
        public void DuplicateCoverage(Coverage coverage)
        {

            Coverage covNew = new Coverage(coverage);

            this.AddCoverage(covNew);




        }


        public ConceptualModel Duplicate()
        {
            return null;
 
        }



        #endregion
    }
}
